﻿using System;
using System.Collections.Generic;
using System.Data;
using MyWeb.Common;

namespace MyWeb.Datamining.Kmeans
{
   public class KmeanProcess
    {
        public int[] Kmean(int k, DataTable dataTable)
        {
            bool kiemtra;
            int soChieu = dataTable.Columns.Count;
            int soLuongDong = dataTable.Rows.Count;
            //Chonj K ph?n t? d?u tiên làm tr?ng tâm
            var listTrongTam = new List<double[]>();
            for (int i = 0; i < k; i++)
            {
                var diem = new double[soChieu];
                for (int j = 0; j < soChieu; j++)
                {
                    diem[j] = double.Parse(dataTable.Rows[i][j].ToString());
                }
                listTrongTam.Add(diem);
            }
            //
            var nhomDoiTuong = new int[soLuongDong];
            //So sánh các di?m v?i tr?ng tâm
            while (true)
            {
                kiemtra = true;
                for (int i = 0; i < dataTable.Rows.Count; i++) //L?p toàn b? các di?m trong table
                {
                    var khoangCach = new double[k]; //danh sách kho?ng cách c?m
                    for (int j = 0; j < k; j++) //l?p s? c?m (tâm)
                    {
                        double[] a = ConvertRowToArrayList(dataTable.Rows[i]);
                        double[] b = listTrongTam[j];
                        khoangCach[j] = TinhKhoangCach(a, b);
                    }
                    int index = GetIndexMax(khoangCach);
                    if (nhomDoiTuong[i] != index)
                    {
                        nhomDoiTuong[i] = index;
                        kiemtra = false;
                    }
                }
                //Tính l?i tâm
                for (int i = 0; i < k; i++) //l?p toàn b? tâm
                {
                    var listDiem = new List<double[]>();
                    for (int j = 0; j < soLuongDong; j++) //l?p toàn b? dòng
                    {
                        if (nhomDoiTuong[j] == i)
                        {
                            double[] a = ConvertRowToArrayList(dataTable.Rows[j]);
                            listDiem.Add(a);
                        }
                    }
                    listTrongTam[i] = TinhTrongTam(listDiem);
                    //ImportArrayList(TinhTrongTam(listDiem));
                }

                if (kiemtra)
                {
                    break;
                }
            }
            return nhomDoiTuong;
        }

        private double TinhKhoangCach(double[] A, double[] B)
        {
            double tong = 0;
            for (int i = 0; i < A.GetLength(0); i++)
            {
                tong += (A[i] - B[i]) * (A[i] - B[i]);
            }
            return Math.Sqrt(tong);
        }

        private int GetIndexMax(double[] phanTu)
        {
            int a = 0;
            double max = phanTu[0];
            for (int i = 0; i < phanTu.GetLength(0); i++)
            {
                if (phanTu[i] < max)
                {
                    max = phanTu[i];
                    a = i;
                }
            }
            return a;
        }

        private double[] ConvertRowToArrayList(DataRow row)
        {
            int soLuong = row.ItemArray.Length;
            var A = new double[soLuong];
            for (int i = 0; i < soLuong; i++)
            {
                A[i] = double.Parse(row[i].ToString());
            }
            //MessageBox.Show(soLuong.ToString());
            return A;
        }

        private double[] TinhTrongTam(List<double[]> diem)
        {
            double[] trongTam = diem[0];
            for (int i = 0; i < trongTam.GetLength(0); i++) //L?p t?t c? thông s? c?a 1 di?m
            {
                double tong = 0;
                for (int j = 0; j < diem.Count; j++) //L?p t?t c? các di?m
                {
                    tong += diem[j][i];
                }
                // MessageBox.Show(tong.ToString());
                trongTam[i] = tong / (diem.Count);
            }
            //ImportArrayList(trongTam);
            return trongTam;
        }
        private void ImportArrayList(double[] mang)
        {
            string a = "";
            for (int i = 0; i < mang.GetLength(0); i++)
            {
                a += mang[i] + ",";
            }
           WebMsgBox.Show(a);
        }
    }
}
